#pragma once

#include <Runtime/Core/Core.h>
#include <Runtime/Graphics/Device/GraphicsDeviceObject.h>
#include "PipelineDesc.h"

class RUNTIME_API Pipeline : public GraphicsDeviceObject {
public:
	Pipeline(std::shared_ptr<GraphicsDevice> device, const PipelineDesc& desc);
	Pipeline(const Pipeline&) = delete;
	Pipeline& operator=(const Pipeline&) = delete;
	virtual ~Pipeline() override = default;

	virtual DeviceObjectType GetDeviceType() noexcept override { return DeviceObjectType::Pipeline; }


	std::vector<std::shared_ptr<Shader>>& GetShaders() { return mShaders; }
	InputLayoutDesc& GetInputLayout() { return mInputLayout; }
	RasterizerDesc& GetRasterizer() { return mRasterizer; }
	DepthStencilDesc& GetDepthStencil() { return mDepthStencil; }
	BlendStateDesc& GetBlend() { return mBlend; }
	std::shared_ptr<Sampler>& GetSampler() { return mSampler; }

	ComPtr<ID3D11InputLayout>& GetInputLayoutObject() { return mInputLayoutObject; }
	ComPtr<ID3D11RasterizerState>& GetRasterizerObject() { return mRasterizerObject; }
	ComPtr<ID3D11DepthStencilState>& GetDepthStencilObject() { return mDepthStencilObject; }
	ComPtr<ID3D11BlendState>& GetBlendObject() { return mBlendObject; }
	ComPtr<ID3D11SamplerState>& GetSamplerObject() { return mSamplerObject; }

	D3D11_PRIMITIVE_TOPOLOGY GetPrimitiveTopology();

private:
	void CreateRasterizerState();
	void CreateDepthStencilState();
	void CreateBlendState();

private:
	std::vector<std::shared_ptr<Shader>> mShaders;
	InputLayoutDesc mInputLayout;
	RasterizerDesc mRasterizer;
	DepthStencilDesc mDepthStencil;
	BlendStateDesc mBlend;
	std::shared_ptr<Sampler> mSampler;

	ComPtr<ID3D11InputLayout> mInputLayoutObject;
	ComPtr<ID3D11RasterizerState> mRasterizerObject;
	ComPtr<ID3D11DepthStencilState> mDepthStencilObject;
	ComPtr<ID3D11BlendState> mBlendObject;
	ComPtr<ID3D11SamplerState> mSamplerObject;

};